using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using C4F.DevKit.DXSoundRecorder;

namespace C4F.DevKit.DXSoundRecorderExample
{
    // Example shows how to use the DXSoundRecorder class library.
    public partial class Window1 : System.Windows.Window
    {
        const SampleRate DefaultRate = SampleRate.Rate44KHz;
        const SampleSize DefaultSize = SampleSize.Bits16;
        const SoundDeviceType DefaultDeviceType = SoundDeviceType.Default;

        SoundRecorder _recorder = null;
        
        SampleRate _samplesPerSecond;
        SampleSize _bitsPerSample;
        SoundDeviceType _deviceType;

        string _filename = string.Empty;
        string _path = string.Empty;
        bool _recording = false;

        // Initialize the window and set the default settings.
        public Window1()
        {
            InitializeComponent();

            this.buttonStartStop.IsEnabled = false;

            this.textBoxFileInfo.Text = "Select a file to record to...";
            this.textBoxRecordInfo.Text = string.Empty;

            this.comboBoxRate.ItemsSource = Enum.GetNames(typeof(SampleRate));
            this.comboBoxRate.SelectedIndex = 0;
            this.comboBoxRate.SelectionChanged += new SelectionChangedEventHandler(comboBoxRate_SelectionChanged);

            this.comboBoxSize.ItemsSource = Enum.GetNames(typeof(SampleSize));
            this.comboBoxSize.SelectedIndex = 0;
            this.comboBoxSize.SelectionChanged += new SelectionChangedEventHandler(comboBoxSize_SelectionChanged);

            this.comboBoxDevice.ItemsSource = Enum.GetNames(typeof(SoundDeviceType));
            this.comboBoxDevice.SelectedIndex = 0;
            this.comboBoxDevice.SelectionChanged += new SelectionChangedEventHandler(comboBoxDevice_SelectionChanged);

            SetDefaultSettings();
        }

        private void SetDefaultSettings()
        {
            if (!Enum.IsDefined(typeof(SampleRate), this._samplesPerSecond))
            {
                this.comboBoxRate.SelectedIndex =
                    this.comboBoxRate.Items.IndexOf(DefaultRate.ToString());
            }
            if (!Enum.IsDefined(typeof(SampleSize), this._bitsPerSample))
            {
                this.comboBoxSize.SelectedIndex =
                    this.comboBoxSize.Items.IndexOf(DefaultSize.ToString());
            }
            if (!Enum.IsDefined(typeof(SoundDeviceType), this._deviceType))
            {
                this.comboBoxDevice.SelectedIndex =
                    this.comboBoxDevice.Items.IndexOf(DefaultDeviceType.ToString());
            }
        }

        private void comboBoxRate_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string selection = e.AddedItems[0] as string;

            this._samplesPerSecond = (SampleRate)Enum.Parse(typeof(SampleRate), selection);
        }

        private void comboBoxSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string selection = e.AddedItems[0] as string;

            this._bitsPerSample = (SampleSize)Enum.Parse(typeof(SampleSize), selection);
        }

        private void comboBoxDevice_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string selection = e.AddedItems[0] as string;

            this._deviceType = (SoundDeviceType)Enum.Parse(typeof(SoundDeviceType), selection);
        }

        private void OnSave(object sender, RoutedEventArgs args)
        {
            OnCreateSoundFile();

            this.buttonStartStop.IsEnabled = true;
        }

        private void OnStartStop(object sender, RoutedEventArgs args)
        {
            if (!this._recording)
            {
                // Start recording...
                try
                {
                    this._recorder = new SoundRecorder(this._deviceType,
                        this._samplesPerSecond, this._bitsPerSample, 1);
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show("Could not create sound recorder: " + ex.Message);
                    return;
                }

                this._recorder.Start(_filename);

                this._recording = true;
                this.buttonStartStop.Content = "Stop";
                string recordBaseMsg = "Recording at {0}KHz and {1}bits/sample using {2} device... click Stop when done.";
                string recordMsg = string.Format(recordBaseMsg,
                    (int)this._samplesPerSecond, (short)this._bitsPerSample, this._deviceType);
                this.textBoxRecordInfo.Text = recordMsg;
            }
            else
            {
                if (this._recording)
                {
                    // Stop recording...
                    this._recorder.Stop();

                    this._recording = false;
                    this.buttonStartStop.Content = "Start";
                    this.textBoxRecordInfo.Text = "Finished recording.";

                    this._recorder.Dispose();
                }
            }
        }

        private void OnCreateSoundFile()
        {
            SaveFileDialog sfd = new SaveFileDialog();
            DialogResult result;

            if (string.Empty == this._path)
            {
                this._path = 
                    Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            }

            sfd.DefaultExt = ".wav";
            sfd.Filter = "Wave Files|*.wav|All Files|*.*";
            sfd.FileName = this._filename;
            sfd.InitialDirectory = this._path;

            this.textBoxFileInfo.Text = "Saving file...";

            // Display the OpenFileName dialog. Then, try to load the specified file
            result = sfd.ShowDialog();

            if (result == System.Windows.Forms.DialogResult.Abort ||
                result == System.Windows.Forms.DialogResult.Cancel)
            {
                this.textBoxFileInfo.Text = "Save aborted.";
                return;
            }
            this._filename = sfd.FileName;

            // Update the UI controls to show the sound as the file is loaded
            this.textBoxFileInfo.Text = "Saving to " + this._filename;
        }
    }
}